#include "kwdb/retry_policy.h"
#include <algorithm>
#include <iostream>
#include <thread>

namespace kwdb {

RetryPolicy::RetryPolicy(const RetryConfig& config)
    : config_(config),
      random_gen_(std::chrono::steady_clock::now().time_since_epoch().count()),
      jitter_dist_(1.0 - config.jitter_factor, 1.0 + config.jitter_factor) {
}

bool RetryPolicy::IsRetryable(int code) const {
    return std::find(config_.retryable_codes.begin(),
                     config_.retryable_codes.end(),
                     code) != config_.retryable_codes.end();
}

std::chrono::milliseconds RetryPolicy::CalculateBackoff(int attempt) {
    // Exponential backoff
    int base_backoff = config_.initial_backoff_ms *
                       std::pow(config_.backoff_multiplier, attempt);

    // Cap at max backoff
    base_backoff = std::min(base_backoff, config_.max_backoff_ms);

    // Add jitter
    double jittered = base_backoff * jitter_dist_(random_gen_);

    return std::chrono::milliseconds(static_cast<int>(jittered));
}

} // namespace kwdb